package com.ng.desktop.fpa.persistence;

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;

import com.linuxense.javadbf.DBFReader;
import com.ng.desktop.fpa.model.DetalleFacturaDBF;
import com.ng.desktop.fpa.model.FacturaDBF;
import com.ng.desktop.fpa.services.NGConfiguration;
import com.ng.framework.persistence.NGGenericPersistenceJPA;

@Repository("detalleFacturaPersistenceDBF")
public class DetalleFacturaPersistenceDBF extends NGGenericPersistenceJPA<DetalleFacturaDBF> {

	private static final Logger LOG = LoggerFactory.getLogger(DetalleFacturaPersistenceDBF.class);

	@Resource(name = "ngConfigurationBean")
	private NGConfiguration configurationBean;

	private DetalleFacturaPersistenceDBF() {
	}

	public Map<String, DetalleFacturaDBF> getAllDetalleFacturaByFacturas(List<FacturaDBF> facturasDBF) {

		Map<String, DetalleFacturaDBF> detallesFacturaDBF = new HashMap<String, DetalleFacturaDBF>();

		Map<String, List<DetalleFacturaDBF>> detallesFacturasAgrupadasMap = new HashMap<String, List<DetalleFacturaDBF>>();

		Map<String, Long> facturasDBFMinValues = new HashMap<String, Long>();

		for (FacturaDBF facturaDBF : facturasDBF) {

			Long minValue = facturasDBFMinValues.get(facturaDBF.getCserie());
			Long nnumfac = Long.valueOf(facturaDBF.getNnumfac());

			if (minValue == null) {
				facturasDBFMinValues.put(facturaDBF.getCserie(), nnumfac);
			} else {
				if (minValue > nnumfac) {
					facturasDBFMinValues.put(facturaDBF.getCserie(), nnumfac);
				}
			}

		}

		DetalleFacturaDBF dbfBuilder = new DetalleFacturaDBF();
		int index = 1;
		try {

			InputStream inputStream = new FileInputStream(configurationBean.getApplicationDBFPath() + "/facclil.dbf");
			DBFReader reader = new DBFReader(inputStream);

			Object[] rowObject;

			int i = 0;

			while ((rowObject = reader.nextRecord()) != null) {

				DetalleFacturaDBF detalleFacturaDBF = dbfBuilder.build(rowObject);
				Long nnumfac = Long.valueOf(detalleFacturaDBF.getNnumfac());
				Long minValue = facturasDBFMinValues.get(detalleFacturaDBF.getCserie());

				if (minValue != null && minValue <= nnumfac) {
					// this.create(detalleFacturaDBF);

					List<DetalleFacturaDBF> detallesFacturasAgrupadasByNroFactura = detallesFacturasAgrupadasMap
							.get(detalleFacturaDBF.getFactura());
					if (detallesFacturasAgrupadasByNroFactura == null) {
						detallesFacturasAgrupadasByNroFactura = new ArrayList<DetalleFacturaDBF>();
						detallesFacturasAgrupadasMap.put(detalleFacturaDBF.getFactura(), detallesFacturasAgrupadasByNroFactura);
					}
					detallesFacturasAgrupadasByNroFactura.add(detalleFacturaDBF);

				}
				if (index % 10000 == 0) {
					LOG.debug("Parseando DetalleFacturaDBF -  Heap Free Size: "
							+ (Runtime.getRuntime().freeMemory() / (1024 * 1024)) + " Bloque: " + index);
				}
				i++;

			}

			LOG.info("Size of " + configurationBean.getApplicationDBFPath() + "/facclil.dbf" + " :" + i);

		} catch (Exception e) {
			e.printStackTrace();
		}
		int i = 0;
		for (FacturaDBF facturaDBF : facturasDBF) {

			if (i % 100 == 0) {
				LOG.debug("Parseando Facturas DBF - Heap Free Size: " + (Runtime.getRuntime().freeMemory() / (1024 * 1024))
						+ " Bloque: " + i);
			}

			List<DetalleFacturaDBF> detallesFacturasAgrupadasByNroFactura = detallesFacturasAgrupadasMap.get(facturaDBF.getKey());

			if (detallesFacturasAgrupadasByNroFactura != null) {
				for (DetalleFacturaDBF detalleFacturaDBF : detallesFacturasAgrupadasByNroFactura) {

					detallesFacturaDBF.put(detalleFacturaDBF.getKey(), detalleFacturaDBF);
				}
			}
			i++;

		}

		return detallesFacturaDBF;
	}

}
